package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.entity.EmployeeExamStatus
import cn.exrick.xboot.base.entity.EnterpriseEmployee
import cn.exrick.xboot.base.entity.SecurityAdvisorJobTrain
import cn.exrick.xboot.base.mapper.EmployeeExamStatusMapper
import cn.exrick.xboot.base.service.*
import cn.exrick.xboot.base.vo.EmployeeExamStatusListVo
import cn.exrick.xboot.base.vo.EmployeeStudyTimeVo
import cn.exrick.xboot.base.vo.JobTrainShowVo
import cn.exrick.xboot.core.common.utils.PageUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.PageVo
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.service.UserService
import cn.hutool.core.date.DateUnit
import cn.hutool.core.date.DateUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.google.common.collect.Maps
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*

/**
 * 员工当前考试状态接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class IEmployeeExamStatusServiceImpl : ServiceImpl<EmployeeExamStatusMapper?, EmployeeExamStatus?>(), IEmployeeExamStatusService {


    @Autowired
    private lateinit var iSecurityAdvisorJobTrainService: ISecurityAdvisorJobTrainService

    @Autowired
    private lateinit var securityUtil: SecurityUtil

    @Autowired
    private lateinit var iEnterpriseEmployeeService: IEnterpriseEmployeeService

    @Autowired
    private lateinit var iEnterpriseCommonParamService: IEnterpriseCommonParamService

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var iJobService: IJobService

    @Autowired
    private lateinit var iEnterpriseUserService: IEnterpriseUserService


    override fun createEmployeeExamStatus(trainId: String): Result<Any?>? {

        //1. 判断有没有到培训开始时间(1.培训开始时间 2.企业培训开始时间)
        if (ToolUtil.getTimestamp(iEnterpriseCommonParamService.getEnterpriseCommonParamLast()?.examStartTime) > ToolUtil.getTimestamp(Date())) {

            return ResultUtil.error(201, "还没到企业开始培训时间")
        }

        if (ToolUtil.getTimestamp(iSecurityAdvisorJobTrainService.getById(trainId)?.trainBeginTime) > ToolUtil.getTimestamp(Date())) {

            return ResultUtil.error(201, "还没到开始培训时间")
        }

        if (ToolUtil.getTimestamp(iSecurityAdvisorJobTrainService.getById(trainId)?.trainEndTime) < ToolUtil.getTimestamp(Date())) {

            return ResultUtil.error(201, "已经到培训截至时间")
        }
        //2. 插入到状态表
        return try {

            getOne(KtQueryWrapper(EmployeeExamStatus::class.java)
                    .eq(EmployeeExamStatus::jobTrainId, trainId)
                    .eq(EmployeeExamStatus::createBy, securityUtil.currUser.id)) ?: save(EmployeeExamStatus().apply {

                jobTrainId = trainId
                jobType = iSecurityAdvisorJobTrainService.getById(trainId)?.jobType
            })
            ResultUtil.success("开始学习成功")
        } catch (e : Exception) {

            ResultUtil.error(e.message)
        }

    }

    override fun getEmployeeStudyTime(pageVo: PageVo, enterpriseId: String?): Result<MutableMap<String, Any?>>? {


        val id = if (ToolUtil.isEmpty(enterpriseId)) iEnterpriseUserService.getEnterpriseIdByEmployeeUserId(securityUtil.currUser.id) else enterpriseId

        return ToolUtil.setListToNul(iEnterpriseEmployeeService.list(KtQueryWrapper(EnterpriseEmployee::class.java).eq(EnterpriseEmployee::enterpriseId, id)
                .orderByDesc(EnterpriseEmployee::createTime)))?.run {

            val result: MutableMap<String, Any?> = Maps.newHashMap()
            result["size"] = size
            result["content"] = PageUtil.listToPage(pageVo, mapNotNull {

                EmployeeStudyTimeVo().apply {

                    userService.get(it?.userId)?.let {

                        ToolUtil.copyProperties(it, this)
                    }
                    jobName = it?.jobId?.let { iJobService.getJobName(it) }
                    studyTime = ToolUtil.setListToNul(list(KtQueryWrapper(EmployeeExamStatus::class.java).eq(EmployeeExamStatus::createBy, it?.userId)))?.run {

                        map { DateUtil.between(it?.createTime, it?.endTime, DateUnit.HOUR) }.reduce { acc, i -> acc + i }
                    } ?: 0
                }
            }.sortedBy { it.studyTime })

            ResultUtil.data(result, "获取学习数据成功")
        } ?: ResultUtil.error(201, "暂无数据")
    }

    override fun getEmployeeTrainingList(pageVo: PageVo, jobType: Int): Result<MutableMap<String, Any?>>? {

        return ToolUtil.setListToNul(iSecurityAdvisorJobTrainService.list(KtQueryWrapper(SecurityAdvisorJobTrain::class.java).eq(SecurityAdvisorJobTrain::jobId, iEnterpriseEmployeeService
                .getJobIdByEmployeeId(securityUtil.currUser.id))
                .eq(SecurityAdvisorJobTrain::jobType, jobType)
                .orderByDesc(SecurityAdvisorJobTrain::createTime)))
                ?.run {

                    val result: MutableMap<String, Any?> = Maps.newHashMap()
                    result["size"] = size
                    result["content"] = PageUtil.listToPage(pageVo, mapNotNull { getEmployeeExamStatusListVo(it!!.id) })
                    result["jobType"] = jobType

                    ResultUtil.data(result, "获取岗位培训列表成功")
                } ?: ResultUtil.error(201, "暂无数据")
    }

    override fun getMyEmployeeTrainingList(pageVo: PageVo, jobType: Int): Result<MutableMap<String, Any?>>? {

        return ToolUtil.setListToNul(list(KtQueryWrapper(EmployeeExamStatus::class.java)
                .eq(EmployeeExamStatus::jobType, jobType)
                .eq(EmployeeExamStatus::createBy, securityUtil.currUser.id)
                .orderByDesc(EmployeeExamStatus::createTime)))
                ?.run {

                    val result: MutableMap<String, Any?> = Maps.newHashMap()
                    result["size"] = size
                    result["content"] = PageUtil.listToPage(pageVo, mapNotNull { getEmployeeExamStatusListVo(it!!.jobTrainId!!) })

                    ResultUtil.data(result, "获取岗位培训列表成功")
                } ?: ResultUtil.error(201, "暂无数据")
    }


    override fun getEmployeeTrainShow(employeeUserId: String): Result<MutableMap<String, Any?>>? {

        return userService.get(employeeUserId)?.run {


            val result: MutableMap<String, Any?> = Maps.newHashMap()
            result["employeeInfo"] = iEnterpriseEmployeeService.getEmployeeInfo(employeeUserId)
            result["trainInfo"] = JobTrainShowVo().apply {

                getOne(KtQueryWrapper(EmployeeExamStatus::class.java).eq(EmployeeExamStatus::createBy, employeeUserId)
                        .orderByDesc(EmployeeExamStatus::createTime)
                        .last("limit 1"))
                        ?.run {

                            iSecurityAdvisorJobTrainService.getById(jobTrainId)?.run {

                                ToolUtil.copyProperties(this, this@apply)

                            }
                            ToolUtil.copyProperties(this, this@apply)
                        }
            }

            ResultUtil.data(result, "获取展示数据成功!")
        } ?: ResultUtil.error(201,"不存在当前用户!")
    }


    override fun getEmployeeExamStatusListVo(trainId: String): EmployeeExamStatusListVo? {

        return iSecurityAdvisorJobTrainService.getById(trainId)?.run {

            EmployeeExamStatusListVo().apply {

                ToolUtil.copyProperties(this@run, this)
                this.trainId = id
                trainPic = trainPics?.split(",")?.get(0)
                getOne(KtQueryWrapper(EmployeeExamStatus::class.java).eq(EmployeeExamStatus::jobTrainId, trainId)
                        .eq(EmployeeExamStatus::createBy, securityUtil.currUser.id))?.let {

                    ToolUtil.copyProperties(it, this)
                    studyStatus = if (it.completeProcess == 5) 3 else 2
                }
            }
        }
    }
}

